/*
 * FileName: getopt.c
 * Author: 李波(Edwin Lee)
 * Date: 2024-08-08 13:44:07
 * Version: 1.0
 * Description: 函数getopt测试
 * getopt() 方法是用来分析命令行参数的，该方法由 Unix 标准库提供，包含在 <unistd.h> 头文件中。
 *
 * 定义：
 * int getopt(int argc, char * const argv[], const char *optstring);
 * extern char *optarg;
 * extern int optind, opterr, optopt;
 *
 * getopt 参数说明：
 * argc：通常由 main 函数直接传入，表示参数的数量
 * argv：通常也由 main 函数直接传入，表示参数的字符串变量数组
 * optstring：一个包含正确的参数选项字符串，用于参数的解析。例如 “abc:d::”，其中 -a，-b 就表示两个没有参数的普通选项，-c 表示一个必须有参数的选项，因为它后面有一个冒号,参数可以带空格也可以不带空格，没写参数会出错；-d 表示一个可有可无参数的选项，因为它后面有一个::，参数不能带空格
 *
 * 外部变量说明：
 * optarg：如果某个选项有参数，这包含当前选项的参数字符串
 * optind：argv 的当前索引值
 * opterr：正常运行状态下为 0。非零时表示存在无效选项或者缺少选项参数，并输出其错误信息
 * optopt：当发现无效选项字符时，即 getopt() 方法返回 ? 字符，optopt 中包含的就是发现的无效选项字符
 */

#include <stdio.h>
#include <unistd.h>

// 执行命令：./getopt -a -b bb -c cc -ddd
int main(int argc, char *argv[]) {
    int o;
		// 有四个选项-a -b -c -d,其中c选项后有冒号，所以后面必须有参数，d选项后面有双冒号，此选项可有可无
    const char *optstring = "abc:d::"; 
    while ((o = getopt(argc, argv, optstring)) != -1) {
        switch (o) {
            case 'a':
                printf("opt is a, oprarg is: %s\n", optarg);
                break;
            case 'b':
                printf("opt is b, oprarg is: %s\n", optarg);
                break;
            case 'c':
                printf("opt is c, oprarg is: %s\n", optarg);
                break;
            case 'd':
                printf("opt is d, oprarg is: %s\n", optarg);
                break;
            case '?':
								printf("get '?'\n");
                printf("error optopt: %c\n", optopt);
                printf("error opterr: %d\n", opterr);
                break;
								// 如果optstring第一个参数为:例如":abc:",且-c没有输入参数，那么返回结果为':',如果第一个参数没有:那么返回'?'
						case ':':
								printf("get ':'\n");
								printf("error optopt:%c\n",optopt);
                printf("error opterr: %d\n", opterr);
								break;
						default:
								break;

        }
    }
    return 0;

}
